#include				<iostream>
#include				"Square.hpp"

Square::Square(int posX, int posY, Box &squareInfo, std::map<int, Square*> &squareMap)
	: _posX(posX), _posY(posY), _display(false), _key(BOX_NUM(_posX, _posY)), _squareInfo(squareInfo), _squareMap(squareMap)
{
}

Square::~Square()
{
}

void						displaycul(long long int var)
{
	int						j = 1;
	for (int i = 360 ; i >= 0 ; --i)
	{
		if (var == 0)
			std::cout << "0 ";
		else
			std::cout << "1 ";
		if (!(j++ % 19))
			std::cout << std::endl;
	}
	std::cout << std::endl;
}

void					Square::putStone(std::string stonePath)
{
	_stoneTexture.loadFromFile(stonePath);
	_stone.setTexture(_stoneTexture);
	_stone.setPosition((float)_posX, (float)_posY);
	_color = (((stonePath) == (BLACK_STONE_PATH)) ? false : true);
	_squareInfo.states |= (1 << 0);
	if (_color)
		_squareInfo.states |= (1 << 1);
	smellManager(TRUE);
	_display = true;
	//displaycul(_squareInfo.directions);
}

void					Square::removeStone()
{
	std::cout << ((_color) ? "White":"Black") << " stone removed" << std::endl;
	setSmell(0, 0, _color, FALSE);
	smellManager(FALSE);
	_squareInfo.states &= (0 << 0);
	if (_color)
		_squareInfo.states &= (0 << 1);
	_display = false;
}

bool			const	Square::displayable() const
{
	return (_display);
}



void					Square::setSmell(int smellPower, short direction, int color, int option)
{
	int					byteDirection = (4 * direction);
	int					pos = ((direction % 2) ? (smellPower - 1) :  (4 - smellPower));

	if (option == 1)
	{
		_squareInfo.directions |= (TRUE << (pos + byteDirection));
		if (color)
			_squareInfo.directions |= (TRUE << ((pos + 32) + byteDirection));
	}
	else
	{
		_squareInfo.directions &= ~(TRUE << (pos + byteDirection));
		if (color)
			_squareInfo.directions &= ~(TRUE << ((pos + 32) + byteDirection));
	}
}

void						Square::spreadSmell(int key, int smellPower, short direction, bool &state, int option)
{
	if (!state)
	{
		if (RIGHT_DIRECTION(direction) && !(key % 19))
		{
			state = true;
			return ;
		}
		else if (LEFT_DIRECTION(direction) && !((key + 1) % 19))
		{
			state = true;
			return ;
		}
		if (KEY_VALIDITY(key))
			_squareMap[key]->setSmell(smellPower, direction, _color, option);
	}
}

void						Square::smellManager(int option)
{
	bool					*state = new bool[8]();

	for (int j = 1; j < 5; j++)
	{
		spreadSmell((_key - j), j, RIGHT, state[0], option);
		spreadSmell((_key + j), j, LEFT, state[1], option);
		spreadSmell((_key + (j * GOBAN_BOX_PER_LINE)), j, UP, state[2], option);
		spreadSmell((_key - (j * GOBAN_BOX_PER_LINE)), j, DOWN, state[3], option);
		spreadSmell((_key + (j * GOBAN_BOX_PER_LINE) + j), j, DIAG_UP_LEFT, state[4], option);	
		spreadSmell((_key - (j * GOBAN_BOX_PER_LINE) - j), j, DIAG_DOWN_RIGHT, state[5], option);
		spreadSmell((_key - (j * GOBAN_BOX_PER_LINE) + j), j, DIAG_DOWN_LEFT, state[6], option);
		spreadSmell((_key + (j * GOBAN_BOX_PER_LINE) - j), j, DIAG_UP_RIGHT, state[7], option);
	}
}


void					Square::setDisplay()
{
	if (_display)
		_display = false;
}

sf::Sprite		const	&Square::getStone() const
{
	return (_stone);
}

Box				const   &Square::getInfo()
{
	return (_squareInfo);
}